#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;
use lib '.';
use Infinite::Sequence qw{:all};


# DEMO: sequence

# sequences are lazy -- evaluation is done during 'take'
# 'show' simply formats ordinary perl array for output
# 'say' simply appends qq{\n} after print
say q{First 25 primes: }, show take 25 => Primes;


# DEMO: combined pattern sequence

# you can combine sequences with constants
my $combined = -10 + Odd;
# $combined now holds a sequence of Odd elements - 10 each ( -9, -7, -5 ... )

# you can combine sequences with other sequences
# result_n = a_n + b_n
$combined += Primes;

$combined *= Pattern( 1, 0, -1 );
# pattern sequence is 1, 0, -1, 1, 0, -1, 1 ...

# multiply every element by -1.1
$combined *= -11;
$combined /= 10;

# again, evaluation is done during 'take'
say q{Combined pattern sequence example: }, show take 10 => $combined;


# DEMO: union set

# infinite set arithmetic works only if
# sets are constructed from ascending sequences.
# a Guard will throw an exception if
# sequence breaks ascension during evaluation

say q{Union example: }, show take 20 =>
    ( SET Even - Pattern(0,1/5) ) + SET( Odd - 10 ) + SET( Naturals / 2 );


# DEMO: intersection and complement set

say q{Not even multiples of 3 and 5: },
	show take 15 => SET( SET(Naturals*3) x SET(Naturals*5) ) - SET Even;

# DEMO: approximations using series

# golden ratio = convergence of ratios of consequent fibonacci numbers
my @fibs = take 1_000 => Fibonacci;
my $phi = pop( @fibs ) / pop( @fibs );
say q{phi ~ }, $phi;

# e = Summation of factorial reciprocals
say q{  e ~ }, SUM 0..100 => 1 / Factorials;

# pi/4 = Summation of Leibniz series
say q{ pi ~ }, ( 4 * SUM 0..1000 => Pattern( 1, -1 ) * ( 1 / Odd ) ),
	q{ Leibniz 1..1001};
	
# pi/2 = Wallis' product
say q{ pi ~ },
	( 2 * PRODUCT 1..1000 => ( Even/(Odd-2) ) * ( Even/Odd ) ),
	q{ Wallis 1..2002};

# phinary_n = phi^n
say q{First 6 phinary: }, show take 6 => $phi ** Naturals;

# DEMO: sequence of random integers within a specified range

say q{Almost naturals: }, show take 15
	=> Naturals + RandomRange( take 10 => Naturals )/10;
